package org.goldenport.g3

import java.io.File

/**
 * @since   May. 11, 2010
 * @version Oct.  8, 2010
 * @author  ASAMI, Tomoharu
 */
trait G3Contextable {
  private var _context: Option[G3Context] = None
  def context: G3Context = _context.get
  protected var is_Log_Info = true
  protected var is_Log_Enter = true
  protected var is_Log_Leave = true
  protected var is_Log_Debug = true

  final def setContext(aContext: G3Context) {
    require (aContext != null)
    _context = Some(aContext)
  }

  final def pushContext(aContext: G3SubContext) {
    require (aContext != null && _context.isDefined)
    aContext.setParent(_context.get)
    _context = Some(aContext)
  }

  protected final def log_info(message: Any, data: Any = None) {
    if (!is_Log_Info) return
    context.logInfo(this, message, data)
//    val className = getClass().getName()
//    println("INFO[" + className + "] " + message)
  }

  protected final def log_enter(name: String, message: Any, data: Any = None) {
    if (!is_Log_Enter) return
    context.logEnter(this, name, message, data)
//    val className = getClass().getName()
//    println("ENTER[" + className + "." + name + "] " + message)
  }

  protected final def log_leave(name: String, message: Any, data: Any = None) {
    if (!is_Log_Leave) return
    context.logLeave(this, name, message, data)
//    val className = getClass().getName()
//    println("LEAVE[" + className + "." + name + "] " + message)
  }

  protected final def log_debug(message: Any, data: Any = None) {
    if (!is_Log_Debug) return
    context.logDebug(this, message, data)
//    val className = getClass().getName()
//    println("DEBUG[" + className + "] " + message)
  }

  protected final def log_info_data(message: Any)(data: => Any) {
    if (!is_Log_Info) return
    context.logInfoData(this, message)(data)
//    val className = getClass().getName()
//    println("INFO[" + className + "] " + message)
  }

  protected final def log_enter_data(name: String, message: Any)(data: => Any) {
    if (!is_Log_Enter) return
    context.logEnterData(this, name, message)(data)
//    val className = getClass().getName()
//    println("ENTER[" + className + "." + name + "] " + message)
  }

  protected final def log_leave_data(name: String, message: Any)(data: => Any) {
    if (!is_Log_Leave) return
    context.logLeaveData(this, name, message)(data)
//    val className = getClass().getName()
//    println("LEAVE[" + className + "." + name + "] " + message)
  }

  protected final def log_debug_data(message: Any)(data: => Any) {
    if (!is_Log_Debug) return
    context.logDebugData(this, message)(data)
//    val className = getClass().getName()
//    println("DEBUG[" + className + "] " + message)
  }

  protected final def log_snapshot[A](message: Any, properties: Map[Any, Any] = Map.empty)(data: => A): A = {
    val result = data
    if (is_Log_Debug) {
      val m = message + (for ((k, v) <- properties) yield {
        k + ":" + v
      }).mkString("{", ",", "}")
      context.logDebugData(this, m)(result)
    }
    result
  }

  // XXX used?
  protected final def create_work_file(): File = {
    context.createWorkFile()
  }

  // XXX used?
  protected final def create_work_directory(): File = {
    context.createWorkDirectory()
  }

  // XXX used?
  protected final def work_directory(): File = {
    context.workDirectory
  }

  // XXX used?
  protected final def text_encoding: String = "utf-8" // XXX
}
